package com.yiqi.news.wxapi;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.text.TextUtils;
import android.util.Log;

import com.jess.arms.utils.ArmsUtils;
import com.jess.arms.utils.LogUtils;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.modelpay.PayResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.yiqi.news.app.utils.DialogUtil;

import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;


public class WechatSdk implements IWXAPIEventHandler {

    String mAppId;
    Activity mContext;
    IWXAPI api;
    OnResult mListener;

    ProgressDialog loading = null;

    public WechatSdk(Activity context, String appId) {
        //        LogUtil.e(appId);
        mAppId = appId;
        mContext = context;
        api = WXAPIFactory.createWXAPI(mContext, mAppId, true);
        api.registerApp(mAppId);
    }

    public void authorize(final OnResult<SendAuth.Resp> listener) {
        if (!api.isWXAppInstalled()) {
            ArmsUtils.makeText(mContext, "您未安装微信!");
            return;
        }
        mListener = listener;

        LogUtils.warnInfo("send start");
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat_ssdk_supertao";
        boolean ret = api.sendReq(req);
        LogUtils.warnInfo("send end = " + ret);

    }

    public static void shareText(Context context, String text, int scene) {

        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setClassName("com.tencent.mm", scene == 0 ? "com.tencent.mm.ui.tools.ShareImgUI" : "com.tencent.mm.ui.tools.ShareToTimeLineUI");
        intent.setType("text/plain");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra("Kdescription", text);
        intent.putExtra(Intent.EXTRA_TEXT, text);
        context.startActivity(intent);
    }

    public void share(String title, String desc, String photo, String url, int scene) {

        if (!api.isWXAppInstalled()) {
            ArmsUtils.makeText(mContext, "您未安装微信!");
            return;
        }
        WXWebpageObject obj = new WXWebpageObject();
        obj.webpageUrl = url;

        WXMediaMessage msg = new WXMediaMessage(obj);
        msg.mediaObject = obj;
        msg.title = title;
        msg.description = desc;


        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = String.valueOf(System.currentTimeMillis());
        req.message = msg;
        req.scene = scene;

        Observable.just(req).subscribeOn(Schedulers.newThread()).subscribe(q -> {

            try {
                if (!TextUtils.isEmpty(photo)) {
                    Bitmap bmp = BitmapFactory.decodeStream(new URL(photo).openStream());
                    Bitmap thumb = thumb(bmp, 150, 150);
//                bmp.recycle();
                    msg.setThumbImage(thumb);
                }
                api.sendReq(q);
            } catch (Exception e) {
                e.printStackTrace();
            }

        });
    }


    public void shareText(String text, int scene) {

        if (!api.isWXAppInstalled()) {
            ArmsUtils.makeText(mContext, "您未安装微信!");
            return;
        }
        WXTextObject obj = new WXTextObject();
        obj.text = text;

        WXMediaMessage msg = new WXMediaMessage(obj);
        msg.mediaObject = obj;
//        msg.title = title;
        msg.description = text;

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = String.valueOf(System.currentTimeMillis());
        req.message = msg;
        req.scene = scene;

        api.sendReq(req);
    }

    static byte[] compressImage(Bitmap image, int maxSize, int offset) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            int options = 100;
            int size = baos.toByteArray().length;
            Log.e("compress", "size = " + size);
            while (size / 1024 > maxSize) {
                baos.reset();
                options -= offset;
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);
                size = baos.toByteArray().length;
                Log.e("compress", "size = " + size);
            }
            byte[] toByteArray = baos.toByteArray();
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                }
            }
            return toByteArray;
        } catch (Throwable th) {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e2) {
                }
            }
        }
        return null;
    }

    public void share(Bitmap photo, int scene) {


        try {
            WXImageObject imgObj = new WXImageObject(photo);

            WXMediaMessage msg = new WXMediaMessage();
            msg.mediaObject = imgObj;
            SendMessageToWX.Req req = new SendMessageToWX.Req();

            req.transaction = buildTransaction("img");
            req.message = msg;
            req.scene = scene;
            msg.setThumbImage(thumb(photo, 150, 150));
//            photo.recycle();
            api.sendReq(req);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void share(String photo, int scene) {
        LogUtils.warnInfo("==========>>>>>" + photo);
        if (!api.isWXAppInstalled()) {
            ArmsUtils.makeText(mContext, "您未安装微信!");
            return;
        }

        Observable.just(1).subscribeOn(Schedulers.newThread()).subscribe(q -> {
            try {
                Bitmap bmp = BitmapFactory.decodeStream(new URL(photo).openStream());
                WXImageObject imgObj = new WXImageObject(bmp);
                WXMediaMessage msg = new WXMediaMessage();
                msg.mediaObject = imgObj;
                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("img");
                req.message = msg;
                req.scene = scene;
                msg.setThumbImage(thumb(bmp, 150, 150));
                bmp.recycle();
                api.sendReq(req);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }


    private String buildTransaction(final String type) {
        return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
    }

    public static Bitmap thumb(Bitmap src, int dstWidth, int dstHeight) {
        final int width = src.getWidth();
        final int height = src.getHeight();
        final float sx = dstWidth / (float) width;
        final float sy = dstHeight / (float) height;
        Matrix m = new Matrix();
        m.setScale(sx, sy);
        Bitmap dst = Bitmap.createBitmap(dstWidth, dstHeight, Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(dst);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(src, m, null);
        return dst;
    }

    public void pay(Map<String, String> params) {
        PayReq req = new PayReq();
        req.appId = mAppId;
        req.partnerId = params.get("partnerid");
        req.prepayId = params.get("prepayid");
        req.packageValue = params.get("packageValue");
        req.nonceStr = params.get("noncestr");
        req.timeStamp = params.get("timestamp");
        req.sign = params.get("sign");
        boolean ret = api.sendReq(req);
        LogUtils.warnInfo("send end = " + ret);

    }

    public void pay(String order, final OnResult<PayResp> listener) {
        mListener = listener;
        PayReq req = new PayReq();
        req.appId = mAppId;
        try {
            LogUtils.warnInfo(mAppId + "================" + order + "----pay");

            JSONObject o = new JSONObject(order);
            req.partnerId = o.getString("partnerid");
            req.prepayId = o.getString("prepayid");
            req.packageValue = o.getString("package");
            req.nonceStr = o.getString("noncestr");
            req.timeStamp = o.getString("timestamp");
            req.sign = o.getString("sign");
        } catch (Exception e) {
            e.printStackTrace();
        }
        boolean ret = api.sendReq(req);
        if (ret) {
            loading = DialogUtil.showLoading(mContext);
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode != 1999 || mListener == null) {
            return;
        }
        LogUtils.warnInfo("==============>>>>onActivityResult");
        api.handleIntent(data, this);
    }


    public interface OnResult<T extends BaseResp> {
        void onResult(T info);
    }


    public void onWXPayEvent(Intent data) {
        api.handleIntent(data, this);
    }

    @Override
    public void onReq(BaseReq req) {
        LogUtils.warnInfo("===============");
        LogUtils.warnInfo("req ==> " + req.getType());
        switch (req.getType()) {
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                LogUtils.warnInfo("req.transaction = " + req.transaction);
                ArmsUtils.makeText(mContext, "req.transaction => " + req.transaction);
                break;
            default:
                break;
        }


    }

    @Override
    public void onResp(BaseResp resp) {

        LogUtils.warnInfo("==================>>>t " + resp.transaction + ", type = " + resp.getType() + ", errCode = " + resp.errCode + ", err = " + resp.errStr);
        if (loading != null) {
            loading.dismiss();
            loading = null;
        }
        switch (resp.getType()) {
            case ConstantsAPI.COMMAND_SENDAUTH:
                onAuthResult(resp);
                break;
            case ConstantsAPI.COMMAND_PAY_BY_WX:
                if (mListener == null) {
                    return;
                }
                mListener.onResult(resp);
                break;
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
                break;
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                break;
            default:
                break;
        }
    }

    void onShareResult(BaseResp resp) {
        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                LogUtils.warnInfo("transaction = " + resp.transaction);
                ArmsUtils.makeText(mContext, "transaction => " + resp.transaction);
                mListener.onResult(resp);
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                break;
            default:
                break;
        }
    }

    void onAuthResult(BaseResp resp) {
        LogUtils.warnInfo("==============>>>" + resp.errCode);
        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                SendAuth.Resp sp = (SendAuth.Resp) resp;
                String code = sp.code;

                LogUtils.warnInfo("code = " + code);
                mListener.onResult(sp);
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                ArmsUtils.makeText(mContext, "验证失败!");
                break;
            default:
                break;
        }
    }
}